
#include <QBuffer>
#include <stdint.h>
#include "codingmanager.h"
#include "signaturecoder.h"

namespace Wishmaster
{
	CodingManager::CodingManager() : Singleton<CodingManager>()
	{
		m_coders.append(CoderPtr(new SignatureCoder()));
	}

	CodingManager::~CodingManager()
	{
	}
	
	QByteArray CodingManager::store(const QList<ExtraInfo>& extras)
	{
		QByteArray result;
		// c++0x ftw
		for(QList<ExtraInfo>::const_iterator extra = extras.begin(); extra != extras.end(); ++extra)
		{
			for(QList<CoderPtr>::iterator it = m_coders.begin(); it != m_coders.end(); ++it)
			{
				if((*it)->infoId() == extra->id)
				{
					QByteArray r = (*it)->store(*extra);
					uint16_t id = (uint16_t)(*it)->token();
					uint16_t len = r.length();
					// FIXME endianness
					result.append((char*)&id, 2);
					result.append((char*)&len, 2);
					result.append(r);
					break;
				}
			}
		}
		return result;
	}

	bool CodingManager::restore(PostPtr& post, const QByteArray& data)
	{
		QBuffer buf(const_cast<QByteArray*>(&data));
		if(!buf.open(QIODevice::ReadOnly))
			return false;
		while(!buf.atEnd())
		{
			uint16_t id, len;
			buf.read((char*)&id, 2);
			buf.read((char*)&len, 2);
			QByteArray arr = buf.read(len);
			CoderPtr coder = coderByToken(id);
			if(coder)
				coder->extract(post, arr);
		}
		return true;
	}

	CoderPtr CodingManager::coderByToken(int token)
	{
		for(QList<CoderPtr>::const_iterator it = m_coders.begin(); it != m_coders.end(); ++it)
		{
			if((*it)->token() == token)
				return *it;
		}
		return CoderPtr();
	}
}

